﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.IO;
using skhukb.DB;
using skhukb.BL;
using skhukb.Models;

namespace skhukb.Controllers
{
    [Authorize]
    public class FileController : Controller
    {
        [HttpGet]
        public ActionResult Upload(UploadModel 모델)
        {
            return View(모델);
        }

        [HttpPost]
        public ActionResult Upload(HttpPostedFileBase filedata, UploadModel 모델)
        {
            System.Threading.Thread.Sleep(1000);
            using (var db = new DBDataContext()) {
                try {
                    var 파일크기제한 = 10;
                    int.TryParse(System.Configuration.ConfigurationManager.AppSettings["FileUploadSizeMax"], out 파일크기제한);

                    string 파일명 = Path.GetFileName(filedata.FileName);
                    var 크기 = (int)filedata.InputStream.Length;
                    if (크기 >= 파일크기제한 * 1024 * 1024) throw new Exception(Consts.파일크기오류);

                    var 버퍼 = new byte[크기];
                    filedata.InputStream.Read(버퍼, 0, 크기);

                    if (모델.type == 1) { // wiki 파일 첨부

                        var 글 = db.글.Single(p => p.ID == 모델.articleId);

                        var 새파일 = new 파일 { 크기 = 크기, 파일명 = 파일명, 내용 = 버퍼, 생성일 = DateTime.Now, 사용자ID = 현재사용자.사용자.ID };
                        db.파일.InsertOnSubmit(새파일);
                        db.SubmitChanges();
                        var 새파일첨부 = new 파일첨부 { 주제ID = 글.주제ID, 글코드 = 글.코드, 파일ID = 새파일.ID };
                        db.파일첨부.InsertOnSubmit(새파일첨부);
                        주제변경내역.파일첨부(db, 글.주제ID, 글.제목, 새파일);
                        db.SubmitChanges();

                    } else if (모델.type == 2) { // bbs 파일 첨부

                        var 글 = db.게시글.FirstOrDefault(p => p.ID == 모델.articleId);
                        if (글 == null) throw new Exception(Consts.글없음);
                        if (BL.게시판.글수정권한(글) == false) throw new Exception(Consts.권한없음);

                        var 새파일 = new 게시글첨부파일 { 크기 = 크기, 파일명 = 파일명, 내용 = 버퍼, 게시글ID = 모델.articleId };
                        db.게시글첨부파일.InsertOnSubmit(새파일);
                        db.SubmitChanges();

                    } else {
                        return HttpNotFound();
                    }                    
                    모델.작업성공 = true;
                    return View(모델);
                } catch (Exception ex) {
                    모델.작업성공 = false;
                    모델.에러메시지 = ex.Message;
                    return View(모델);
                }
            }        
        }

        [HttpGet]
        public ActionResult List(long articleId, int type)
        {
            using (var db = new DBDataContext()) {
                if (type == 1) {
                    var 글 = db.글.Single(p => p.ID == articleId);
                    var 목록 = db.파일첨부.Where(p => p.주제ID == 글.주제ID && p.글코드 == 글.코드).Select(p => new 파일Model(p.파일)).ToList();
                    return PartialView("_List", new FileListModel { 목록 = 목록, 글ID = articleId, type = type });
                } else if (type == 2) {
                    var 목록 = db.게시글첨부파일.Where(p => p.게시글ID == articleId).Select(p => new 파일Model(p)).ToList();
                    return PartialView("_List", new FileListModel { 목록 = 목록, 글ID = articleId, type = type });
                }
                return HttpNotFound();
            }
        }

        [HttpGet]
        public ActionResult Download(long id, int type)
        {
            using (var db = new DBDataContext()) {
                if (type == 1) {
                    var 파일 = db.파일.FirstOrDefault(p => p.ID == id);
                    if (파일 == null) return HttpNotFound();
                    return File(파일.내용.ToArray(), "application/octet-stream", 파일.파일명);
                } else if (type == 2) {
                    var 파일 = db.게시글첨부파일.FirstOrDefault(p => p.ID == id);
                    if (파일 == null) return HttpNotFound();
                    return File(파일.내용.ToArray(), "application/octet-stream", 파일.파일명);
                }
                return HttpNotFound();
            }
        }

        [skhukb.Util.AjaxOnly] [HttpPost]
        public ActionResult Delete(long id, int type)
        {
            using (var db = new DBDataContext()) {
                if (type == 1) {
                    // 첨부 파일은 버전 관리를 하지 않는다. 파일을 삭제하면, 모든 버전에서 파일이 동시에 삭제된다.
                    var 파일 = db.파일.FirstOrDefault(p => p.ID == id);
                    if (파일 == null) return Json(new JsonModel { success = false, message = Consts.작업실패 });

                    var 첨부 = 파일.파일첨부.First();
                    var 글 = db.글.First(p => p.주제ID == 첨부.주제ID && p.코드 == 첨부.글코드);

                    주제변경내역.파일삭제(db, 글.주제ID, 글.제목, 파일);
                    db.파일첨부.DeleteAllOnSubmit(파일.파일첨부);
                    db.파일.DeleteOnSubmit(파일);
                    db.SubmitChanges();
                    return Json(new JsonModel { success = true });

                } else if (type == 2) {
                    var 파일 = db.게시글첨부파일.FirstOrDefault(p => p.ID == id);
                    if (파일 == null) return Json(new JsonModel { success = false, message = Consts.작업실패 });
                    if (BL.게시판.글수정권한(파일.게시글) == false) return Json(new JsonModel { success = false, message = Consts.권한없음 });

                    db.게시글첨부파일.DeleteOnSubmit(파일);
                    db.SubmitChanges();
                    return Json(new JsonModel { success = true });
                }               
                return HttpNotFound();
            }
        }

        [Authorize(Roles = MyRoleProvider.ADMIN)]
        public ActionResult Clean()
        {
            using (var db = new DBDataContext()) {
                int count = 0;
                var 삭제목록 = db.파일첨부.Where(p => db.글.Any(q => q.주제ID == p.주제ID && q.코드 == p.글코드) == false);
                foreach (var p in 삭제목록) {
                    ++count;
                    db.파일첨부.DeleteOnSubmit(p);
                }
                db.파일.DeleteAllOnSubmit(db.파일.Where(p => db.파일첨부.Any(q => q.파일ID == p.ID) == false));
                db.SubmitChanges();
                return View(count);
            }
        }

    }
}
